<template>
  <div id="xplayer">
    <div class="player-container">
      <!-- 视频区域 -->
      <div class="player-video-area">
        <!-- 视频播放器 -->
        <div class="player-video-perch">
          <div class="player-video-wrap">
            <video
              ref="XPlayerRef"
              @play="playVideo"
              @pause="pauseVideo"
              controls
              style="width: 100%; height: 100%; object-fit: cover"
            >
              <source preload="auto" src="@/assets/video/wuting.mp4" />
            </video>
          </div>
          <div v-if="videoLoadError" class="videoLoadError">视频加载失败</div>
        </div>
        <!-- 弹幕层 -->
        <div class="player-bas-dm-wrap" ref="barrageContainer"></div>
      </div>
    </div>
  </div>
</template>
    
<script setup>
import { ref, onUnmounted } from "vue";

const XPlayerRef = ref(null);
const barrageContainer = ref(null);
let timer = null;
let barrageMap = {}; //用于跟踪弹幕是否显示在屏幕上
const barragePause = ref(false); // 控制弹幕暂停
const barragePauseMap = ref([]); // 保存暂停的动画
const barrageList = ref([
  {
    content: "好听",
    user: "lake",
    sendTime: "00.02",
    barrType: "base",
    left: "100",
    position: 100, // 初始位置在弹幕容器外部
    animationPlayState: "paused", // 控制弹幕动画播放状态
  },
  {
    content: "好听啊",
    user: "lake",
    sendTime: "00.04",
    barrType: "base",
    left: "100", // 起始位置 相对弹幕容器，也是暂停恢复后的起始位置
    position: 100, // 初始位置在弹幕容器外部
    animationPlayState: "paused", // 控制弹幕动画播放状态
  },
]);

let animationFrameId = null;

const playVideo = () => {
  if (XPlayerRef.value) {
    XPlayerRef.value.play();
  }

  handlePlay();
};

const pauseVideo = () => {
  if (XPlayerRef.value) {
    XPlayerRef.value.pause();
  }

  handlePause();
};

const handlePlay = () => {
  console.log("开始运行弹幕");
  barrageList.value.forEach((barrage) => {
    if (barrage.element) {
      barrage.element.style.animationPlayState = "running";
    }
  });
  if (XPlayerRef.value.currentTime > 0) {
    handleResume();
    console.log("恢复弹幕");
  } else {
    startBarrage();
    console.log("启动弹幕");
  }
};

const handlePause = () => {
  barrageList.value.forEach((barrage) => {
    if (barrage.element) {
      barrage.element.style.animationPlayState = "paused";
    }
  });
  cancelAnimationFrame(animationFrameId);
};

const handleResume = () => {
  animationFrameId = requestAnimationFrame(animateBarrages);
};

// 启动弹幕方法
const startBarrage = () => {
  if (timer) return; //避免计时器重复设置
  timer = setInterval(() => {
    const videoElement = XPlayerRef.value; //获取当前播放器元素
    if (videoElement && videoElement.currentTime) {
      // 遍历弹幕列表，找出当前时间应该显示的弹幕
      for (let i = 0; i < barrageList.value.length; i++) {
        const barrage = barrageList.value[i];
        const sendTimeSeconds = timeStringToSeconds(barrage.sendTime);
        // 如果弹幕发送时间在当前视频时间之前且不在屏幕上，则创建弹幕
        if (
          sendTimeSeconds <= videoElement.currentTime &&
          sendTimeSeconds >= videoElement.currentTime - 2 &&
          !barrageMap[barrage.sendTime]
        ) {
          createBarrage(barrage);
          //   console.log(barrage)
          // 标记该弹幕已经在屏幕上 避免重复弹幕
          barrageMap[barrage.sendTime] = true;
        }
      }
    }
  }, 1000);
};

// 添加弹幕并调用动画方法
const createBarrage = (barrage) => {
  const barrageElement = document.createElement("div");

  barrageElement.textContent = `${barrage.content}:${barrage.sendTime}`; //${barrage.user}:
  barrageElement.className = "barrage"; //目前用来起别名使用
  //直接给新建标签设置样式
  barrageElement.style.position = "absolute";
  barrageElement.style.whiteSpace = "nowrap";
  //初始在容器left的100%处，也就是弹幕显示容器的右侧外部
  barrageElement.style.left = `${barrage.left}%`; // 设置初始位置为容器宽度
  barrageElement.style.color = "#ff0000";
  // 设置弹幕垂直位置，这里假设有轨道逻辑，可以根据实际情况调整
  barrageElement.style.top = `${calculateBarrageTop(barrage)}%`;
  barrageElement.style.animation = "moveBarrage 10s linear forwards";
  barrageElement.style.animationPlayState = "running";
  barrage.element = barrageElement; // 将创建的弹幕元素赋值给barrage对象
  //当新建弹幕元素加入基础弹幕容器中
  barrageContainer.value.appendChild(barrageElement);

  // 开始弹幕动画
  animateBarrages(barrageElement);
};

// 假设calculateBarrageTop是一个函数，用来计算弹幕的垂直位置
const calculateBarrageTop = (barrage) => {
  // 根据弹幕内容、用户或其他逻辑计算弹幕的垂直位置
  // 这里只是一个示例，返回一个随机值
  return Math.floor(Math.random() * 10) * 5; // 假设有10个轨道，每个轨道间隔5%
};

//弹幕动画
/**
 * element 弹幕元素
 * */
const animateBarrages = () => {
  // 弹幕动画被调用
  barrageList.value.forEach((barrage) => {
    if (barrage.element && barrage.animationPlayState === "running") {
      // 获取当前容器的宽度
      const containerWidth = barrageContainer.value.offsetWidth;
      // 弹幕元素移动的起始位置就是弹幕宽度
      const moveTotleWidth = containerWidth + barrage.element.offsetWidth;
      const moveStep = 10; // 移动速度
      // 计算新的left值
      let newLeft = (barrage.element.offsetLeft - moveStep) * 100 / containerWidth;
      // 更新弹幕的位置
      barrage.element.style.left = `${newLeft}%`;

      // 检查弹幕是否已经移出屏幕左侧
      if (barrage.element.offsetLeft + barrage.element.offsetWidth < 0) {
        barrage.element.remove(); // 移除已经滚出屏幕的弹幕
      }
    }
  });

  // 启动动画循环
  animationFrameId = requestAnimationFrame(animateBarrages);
};

// 将时间字符串转换为秒
const timeStringToSeconds = (timeString) => {
  const [minutes, seconds] = timeString.split(".");
  return parseInt(minutes, 10) * 60 + parseFloat(seconds);
};

// 当不再需要弹幕时，清除计时器
const stopBarrage = () => {
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
};

onUnmounted(() => {
  stopBarrage();
  cancelAnimationFrame(animationFrameId);
});
</script>
  <style lang="scss" scoped>
#xplayer {
  position: relative;
}

.player-container {
  display: flex;
  flex-direction: column;
  position: relative;
  width: 100%; /* 视频容器宽度设置为100% */
  height: 100%; /* 视频容器高度设置为100% */
  min-width: 668px; /* 视频容器的最小宽度 */
  max-width: 1100px; /* 视频容器的最大宽度 */
  max-height: 618px; /* 视频容器的最大高度 */
  flex-wrap: nowrap;
  -webkit-box-shadow: 0 0 8px #e5e9ef;
  box-shadow: 0 0 8px #e5e9ef;
  -webkit-box-shadow: 0 0 8px #f1f2f3;
  box-shadow: 0 0 8px #f1f2f3;
}

.player-video-area {
  flex: 1;
  position: relative;
  background-color: #000;
  overflow: hidden;
}

.player-video-wrap {
  position: relative; /* 确保视频容器是相对定位，便于内部元素的定位 */
  overflow: hidden; /* 如果视频尺寸超出容器，将超出部分隐藏 */
}

.player-video-wrap video {
  content-visibility: visible;
  display: block;
  width: 100%; /* 视频宽度设置为100%，使其与容器宽度相同 */
  height: 100%; /* 视频高度设置为100%，使其与容器高度相同 */
  max-width: 100%; /* 确保视频的最大宽度不超过其容器 */
  max-height: 100%; /* 确保视频的最大高度不超过其容器 */
  max-height: 572px;
  object-fit: contain; /* 使用 contain 保持视频的宽高比 */
}

.player-video-perch {
  position: relative;
  //object-fit: contain; /* 使用 contain 保持视频的宽高比 */

  .videoLoadError {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: rgba(255, 255, 255, 0.9);
    text-align: center;
  }
}

/* 弹幕层样式 */
.player-adv-dm-wrap,
.player-bas-dm-wrap,
.player-row-dm-wrap {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  pointer-events: none;
}

.barrage {
  position: absolute;

  &:hover {
    animation-play-state: paused;
  }
}

@keyframes moveBarrage {
  from {
    left: 100%;
  }
  to {
    left: -100%;
  }
}
</style>